package com.quark.framework.utility;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class QuarkLog {
	private static QuarkLog inst = null;
	private static String logFileName = "";
	private static String logFolder = "";
	private static BufferedWriter logFileWriter = null;
	private static File logFile = null; 
	private static int maxFileSize = 1024 * 1024;
	private static String lineA = "===================================================";
	private static String lineB = "---------------------------------------------------";
	private static int lineLength = lineA.length();
	public enum LOG_LEVEL
	{
		LOG_NONE,
		LOG_MESSAGE,
		LOG_DEBUG,
		LOG_ERROR,
	}
	public enum LOG_PRINT_POSITION
	{
		LOG_PRINT_LEFT,
		LOG_PRINT_RIGHT,
		LOG_PRINT_CENTER,
	} 
	
	public static boolean init(String folder)
	{
		boolean ret = false;
		inst = new QuarkLog();
		logFolder = folder + "log\\";
		File logFolderFile = new File(logFolder);
		if(!logFolderFile.exists() && !logFolderFile.mkdir())
			return false;
		logFileName = logFolder + "Hydrogen_Log_" + QuarkUtilDateHelper.getDateTimeString().replace(":", "") + ".txt";		
		logFile = new File(logFileName);	
		
		try 
		{
			if(logFile.createNewFile())
			{
				logFileWriter = new BufferedWriter(new FileWriter(logFile), 10);
				ret = true;
			}
			else
			{ 
				ret = false;
			}
		} catch (IOException e) {
			e.printStackTrace();
			ret = false;
		}
		return ret;
	}
	
	public static boolean newFile()
	{
		logFileName = logFolder + "Hydrogen_Log_" + QuarkUtilDateHelper.getDateString() + ".txt";
		logFile = new File(logFileName);
		try
		{
			logFileWriter.flush();
			logFileWriter.close();
			logFileWriter = new BufferedWriter(new FileWriter(logFile));
			return true;
		}
		catch(Exception e)
		{
			QuarkLog.logError("create new log file failed," + e.getLocalizedMessage());
			return false;
		}		
	}
	
	public static boolean uninit()
	{
		if(inst != null)
		{
			try {
				QuarkLog.logFileWriter.flush();
				QuarkLog.logFileWriter.close();
			} catch (IOException e) {
				log(e);
			}			
		}
		return true;
	}
	public static void splitLine1()
	{
		logToFile(lineA, LOG_LEVEL.LOG_NONE);
	}
	public static void splitLine2()
	{
		logToFile(lineB, LOG_LEVEL.LOG_NONE);
	}
	public static void print(String s)
	{
		logToFile(s, LOG_LEVEL.LOG_NONE);
	}
	public static void println(String s, String head, LOG_PRINT_POSITION pos)
	{
		int blanks = lineLength - s.length() - head.length() * 2;
		if(blanks < 0)
		{
			blanks = lineLength - s.length();
			if(blanks <= 0)
			{
				println(s);
				return;
			}
		}
				
		int halfBlank = blanks / 2; 			
		String blank = "";
		String blankLeft = "";
		String blankRight = "";
		String append = halfBlank * 2 == blanks? "" : " ";
		for(int i = 0; i < halfBlank; i++)
		{
			blank += " ";
		}
		switch(pos)
		{
		case LOG_PRINT_LEFT:
			blankLeft = "";
			blankRight = blank + blank + append;
			break;
		case LOG_PRINT_RIGHT:
			blankLeft = blank + blank + append;
			blankRight = "";
			break;
		default:
			blankLeft = blank + append;
			blankRight = blank;
			break;
		}
		if(blanks < 0)
		{
			logToFile(blankLeft + " " + s + blankRight, LOG_LEVEL.LOG_NONE);
		}
		else
			logToFile(head + blankLeft + " " + s + blankRight + head, LOG_LEVEL.LOG_NONE);
		return;
		
	}
	public static void println(String s)
	{
		logToFile(s, LOG_LEVEL.LOG_NONE);
	}
	//log error according to exception
	public static void log(Exception e)
	{		
		e.printStackTrace();
		log(e.getMessage(), LOG_LEVEL.LOG_ERROR);
		//e.printStackTrace();
	}

	//log message
	public static void logMessage(String head, String msg)
	{
		log(head + ": " + msg, LOG_LEVEL.LOG_MESSAGE);
	}
	
	//log debug
	public static void logDebug(String head, String msg)
	{
		log(head + ": " + msg, LOG_LEVEL.LOG_DEBUG);
	}
	
	//log debug
	public static void logError(String head, String msg)
	{
		log(head + ": " + msg, LOG_LEVEL.LOG_ERROR);
	}
	
	//log message
	public static void logMessage(String msg)
	{
		log(msg, LOG_LEVEL.LOG_MESSAGE);
	}
	
	//log debug
	public static void logDebug(String msg)
	{
		log(msg, LOG_LEVEL.LOG_DEBUG);
	}
	
	//log debug
	public static void logError(String msg)
	{
		log(msg, LOG_LEVEL.LOG_ERROR);
	}
		
	//log default, will be cancelled when publish
	public static void log(String msg)
	{
		log(msg, LOG_LEVEL.LOG_DEBUG);
	}
	
	public static void logToFile(String msg, LOG_LEVEL level)
	{
		if(logFileWriter != null)
		{
			try
			{
				String logHead = "";
				switch(level)
				{
				case LOG_MESSAGE:
					logHead = "[MESSAGE@" + QuarkUtilDateHelper.getDateTimeString() + "]";
					System.out.println(logHead + msg);
					break;
				case LOG_DEBUG:
					logHead = "[DEBUG@" + QuarkUtilDateHelper.getDateTimeString() + "]";
					System.out.println(logHead + msg);
					break;
				case LOG_ERROR:
					logHead = "[ERROR@" + QuarkUtilDateHelper.getDateTimeString() + "]";
					System.err.println(logHead + msg);
					break;
				case LOG_NONE:
					logHead = "";
					System.out.println(logHead + msg);
					break;
					
				}
				logFileWriter.write(logHead + msg);
				logFileWriter.newLine();
				logFileWriter.flush();
				if(logFile.length() > maxFileSize)
				{
					newFile();
				}				
			}
			catch(Exception ie)
			{
				System.err.println("WriteFileError,"+ie.getLocalizedMessage());
			}
		}
		else
		{
			System.err.println("write log file error!");
		}
	}
	public static void logToFile(Exception e)
	{
		e.printStackTrace();
		log(e);
		if(logFileWriter != null)
		{
			try
			{
				String log = "[" + QuarkUtilDateHelper.getDateTimeString() + "]" + e.getMessage();
				logFileWriter.write(log);
				logFileWriter.newLine();
				logFileWriter.flush();
				if(logFile.length() > maxFileSize)
				{
					
					newFile();
				}
			}
			catch(Exception ie)
			{
				System.err.println("WriteFileError,"+ie.getLocalizedMessage());
			}
		}
		else
		{
			System.err.println("write log file error!");
		}
	}
	
	public static void log(String msg, LOG_LEVEL level)
	{
		logToFile(msg, level);
	}
	private QuarkLog()
	{
		
	}
	public void finalize()
	{
		try
		{
			System.out.println("OUT");
			
			try {
				super.finalize();
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}catch(Exception e)
		{
			e.printStackTrace();
		}		
	}

}
